package com.senlingspace.system.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSON;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import com.senlingspace.common.constant.HttpStatus;
import com.senlingspace.common.core.domain.AjaxResult;
import com.senlingspace.common.utils.DateUtils;
import com.senlingspace.common.utils.MoneyUtils;
import com.senlingspace.system.domain.*;
import com.senlingspace.system.domain.dto.ProjectTicketFareManagementDto;
import com.senlingspace.system.domain.vo.ProjectTicketFareManagementVo;
import com.senlingspace.system.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.senlingspace.system.service.ISlkjProjectTicketFareService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 项目_票价Service业务层处理
 *
 * @author SenlingSpace
 * @date 2024-07-03
 */
@Deprecated
@Slf4j
@Service
public class SlkjProjectTicketFareServiceImpl implements ISlkjProjectTicketFareService {
    @Autowired
    private SlkjProjectTicketFareMapper slkjProjectTicketFareMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private SlkjShopProjectMapper slkjShopProjectMapper;
    @Autowired
    private SlkjShopMapper slkjShopMapper;
    @Autowired
    private SlkjTicketCategoryMapper slkjTicketCategoryMapper;
    @Autowired
    private SlkjTicketLevelMapper slkjTicketLevelMapper;


    /**
     * 查询项目_票价
     *
     * @param id 项目_票价主键
     * @return 项目_票价
     */
    @Override
    public SlkjProjectTicketFare selectSlkjProjectTicketFareById(Long id) {
        return slkjProjectTicketFareMapper.selectSlkjProjectTicketFareById(id);
    }

    /**
     * 查询项目_票价列表
     *
     * @param projectId 项目id
     * @return 项目_票价
     */
    @Override
    public AjaxResult selectSlkjProjectTicketFareList(Long projectId) {
        log.info("获取项目 [project_id={}] 票价详情。", projectId);
        Stopwatch stopwatch = Stopwatch.createStarted();
        if (projectId == null) {
            return AjaxResult.error("项目ID不为为空！");
        }

        Project project = projectMapper.selectProjectByProjectId(projectId);
        if (Objects.isNull(project)) {
            return AjaxResult.error("项目ID有误/不存在！");
        }

        // 票档
        List<SlkjTicketLevel> ticketLevels = slkjTicketLevelMapper.selectSlkjTicketLevelList(null);
        if (CollectionUtils.isEmpty(ticketLevels)) {
            return AjaxResult.error(HttpStatus.TICKET_LEVEL_NOT_EXIST, "需要先创建票档/票类，才可以做票价管理！");
        }

        // 票类
        List<SlkjTicketCategory> ticketCategories = slkjTicketCategoryMapper.selectSlkjTicketCategoryList(null);
        if (CollectionUtils.isEmpty(ticketCategories)) {
            return AjaxResult.error(HttpStatus.TICKET_CATEGORY_NOT_EXIST, "需要先创建票档/票类，才可以做票价管理！");
        }

        Map<Long, SlkjShop> shopMap = new HashMap<>();
        // 获取该项目对应门店
        SlkjShopProject shopProject = new SlkjShopProject();
        shopProject.setProjectId(projectId);
        shopProject.setDelFlag((byte) 0);// 0=正常，1=删除
        List<SlkjShopProject> shopProjects = slkjShopProjectMapper.selectSlkjShopProjectList(shopProject);
        if (CollectionUtils.isNotEmpty(shopProjects)) {
            List<Long> shopIds = shopProjects.stream().map(SlkjShopProject::getShopId).collect(Collectors.toList());
            List<SlkjShop> shops = slkjShopMapper.selectSlkjShopListByIds(shopIds);
            shopMap = shops.stream().collect(Collectors.toMap(SlkjShop::getShopId, shop -> shop));
        }

        // 结果集
        final ProjectTicketFareManagementVo result = new ProjectTicketFareManagementVo();
        result.setProjectId(projectId);
        result.setProjectNumber(project.getNumber());
        result.setProjectName(project.getName());
        result.setDefaultUniformPrices(null);
        result.setShopPrices(null);

        Map<Long, SlkjTicketLevel> ticketLevelMap = ticketLevels.stream().collect(Collectors.toMap(SlkjTicketLevel::getId, ticketLevel -> ticketLevel));
        Map<Long, SlkjTicketCategory> ticketCategoryMap = ticketCategories.stream().collect(Collectors.toMap(SlkjTicketCategory::getId, tc -> tc));
        Map<Long, List<SlkjTicketCategory>> ticketCategoryMapList = ticketCategories.stream().collect(Collectors.groupingBy(SlkjTicketCategory::getTicketLevelId));

        // 票价管理
        SlkjProjectTicketFare projectTicketFare = new SlkjProjectTicketFare();
        projectTicketFare.setProjectId(projectId);
        projectTicketFare.setStatus(1);
        List<SlkjProjectTicketFare> projectTicketFares = slkjProjectTicketFareMapper.selectSlkjProjectTicketFareList(projectTicketFare);

        List<ProjectTicketFareManagementVo.UniformPrice> defaultUniformPrices;
        List<ProjectTicketFareManagementVo.ShopPrice> shopPrices;

        // 首次设置价格
        if (CollectionUtils.isEmpty(projectTicketFares)) {
            log.info("该项目还未做过票价管理设置。");
            defaultUniformPrices = new ArrayList<>();
            ticketCategoryMapList.forEach((ticketLevelId, ticketCategoryList) -> {
                ProjectTicketFareManagementVo.UniformPrice uniformPrice = new ProjectTicketFareManagementVo.UniformPrice();
                SlkjTicketLevel ticketLevel = ticketLevelMap.get(ticketLevelId);
                uniformPrice.setTicketLevelId(ticketLevel.getId());
                uniformPrice.setTicketLevelName(ticketLevel.getName());
                List<ProjectTicketFareManagementVo.UniformPriceDetail> details = getUniformPriceDetails(ticketCategoryList);
                uniformPrice.setDetails(details);
                defaultUniformPrices.add(uniformPrice);
            });
            result.setDefaultUniformPrices(defaultUniformPrices);

            if (CollectionUtils.isEmpty(shopProjects)) {
                result.setShopPrices(Lists.newArrayList());
                return AjaxResult.success(result);
            }

            shopPrices = new ArrayList<>();
            Map<Long, SlkjShop> finalShopMap = shopMap;
            shopProjects.forEach(sp -> {
                if (finalShopMap.containsKey(sp.getShopId())) {
                    ProjectTicketFareManagementVo.ShopPrice shopPrice = new ProjectTicketFareManagementVo.ShopPrice();
                    SlkjShop shop = finalShopMap.get(sp.getShopId());
                    shopPrice.setShopId(sp.getShopId());
                    shopPrice.setShopName(shop.getShopName());
                    shopPrice.setShopNumber(shop.getShopNo());
                    List<ProjectTicketFareManagementVo.ShopPriceDetail> details = new ArrayList<>();
                    ticketCategoryMapList.forEach((ticketLevelId, ticketCategoryList) -> {
                        ticketCategoryList.forEach(ticketCategory -> {
                            ProjectTicketFareManagementVo.ShopPriceDetail shopPriceDetail = new ProjectTicketFareManagementVo.ShopPriceDetail();
                            shopPriceDetail.setTicketCategoryId(ticketCategory.getId());
                            shopPriceDetail.setTicketCategoryName(ticketCategory.getName());
                            SlkjTicketLevel ticketLevel = ticketLevelMap.get(ticketLevelId);
                            shopPriceDetail.setTicketLevelId(ticketLevel.getId());
                            shopPriceDetail.setTicketLevelName(ticketLevel.getName());
                            shopPriceDetail.setShopPrice("");
                            details.add(shopPriceDetail);
                        });
                    });
                    shopPrice.setDetails(details);
                    shopPrices.add(shopPrice);
                }
            });
            result.setShopPrices(shopPrices);
            log.info("项目 [project_id={}] 结果集：{}.", projectId, JSON.toJSONString(result));
            log.info("数据获取组装，共耗时：{}.", stopwatch.stop());
            return AjaxResult.success(result);
        }

        log.info("该项目已经有过价格设置。");
        // 非首次设置票价
        defaultUniformPrices = new ArrayList<>();
        // 统一价
        projectTicketFares.stream()
                .filter(fare -> Objects.isNull(fare.getShopPrice()))
                .collect(Collectors.groupingBy(SlkjProjectTicketFare::getTicketLevelId))
                .forEach((ticketLevelId, ticketFareList) -> {
                    SlkjProjectTicketFare fare = ticketFareList.get(0);
                    ProjectTicketFareManagementVo.UniformPrice uniformPrice = new ProjectTicketFareManagementVo.UniformPrice();
                    uniformPrice.setTicketLevelId(fare.getTicketLevelId());
                    uniformPrice.setTicketLevelName(ticketLevelMap.get(fare.getTicketLevelId()).getName());
                    List<ProjectTicketFareManagementVo.UniformPriceDetail> details = new ArrayList<>();
                    for (SlkjProjectTicketFare ticketFare : ticketFareList) {
                        ProjectTicketFareManagementVo.UniformPriceDetail uniformPriceDetail = new ProjectTicketFareManagementVo.UniformPriceDetail();
                        uniformPriceDetail.setTicketCategoryId(ticketFare.getTicketCategoryId());
                        uniformPriceDetail.setTicketCategoryName(ticketCategoryMap.get(ticketFare.getTicketCategoryId()).getName());
                        Long price = ticketFare.getUniformPrice();
                        uniformPriceDetail.setUniformPrice(Objects.isNull(price) ? "" : MoneyUtils.fen2Yuan(price));
                        details.add(uniformPriceDetail);
                    }
                    uniformPrice.setDetails(details);
                    defaultUniformPrices.add(uniformPrice);
                });
        result.setDefaultUniformPrices(defaultUniformPrices);

        // 门店价
        shopPrices = new ArrayList<>();
        Map<Long, SlkjShop> finalShopMap1 = shopMap;
        projectTicketFares.stream()
                .filter(fare -> !Objects.isNull(fare.getShopPrice()))
                .collect(Collectors.groupingBy(SlkjProjectTicketFare::getStoreId))
                .forEach((storeId, ticketFareList) -> {
                    ProjectTicketFareManagementVo.ShopPrice shopPrice = new ProjectTicketFareManagementVo.ShopPrice();
                    SlkjShop shop = finalShopMap1.get(storeId);
                    shopPrice.setShopId(storeId);
                    shopPrice.setShopName(shop.getShopName());
                    shopPrice.setShopNumber(shop.getShopNo());
                    List<ProjectTicketFareManagementVo.ShopPriceDetail> details = new ArrayList<>();
                    for (SlkjProjectTicketFare ticketFare : ticketFareList) {
                        ProjectTicketFareManagementVo.ShopPriceDetail shopPriceDetail = new ProjectTicketFareManagementVo.ShopPriceDetail();
                        shopPriceDetail.setTicketCategoryId(ticketFare.getTicketCategoryId());
                        shopPriceDetail.setTicketCategoryName(ticketCategoryMap.get(ticketFare.getTicketCategoryId()).getName());
                        shopPriceDetail.setTicketLevelId(ticketFare.getTicketLevelId());
                        shopPriceDetail.setTicketLevelName(ticketLevelMap.get(ticketFare.getTicketLevelId()).getName());
                        Long price = ticketFare.getShopPrice();
                        shopPriceDetail.setShopPrice(Objects.isNull(price) ? "" : MoneyUtils.fen2Yuan(price));
                        details.add(shopPriceDetail);
                    }
                    shopPrice.setDetails(details);
                    shopPrices.add(shopPrice);
                });
        result.setShopPrices(shopPrices);

        log.info("项目 [project_id={}] 结果集：{}.", projectId, JSON.toJSONString(result));
        log.info("数据获取组装，共耗时：{}.", stopwatch.stop());
        return AjaxResult.success(result);
    }

    private static List<ProjectTicketFareManagementVo.UniformPriceDetail> getUniformPriceDetails(List<SlkjTicketCategory> ticketCategoryList) {
        List<ProjectTicketFareManagementVo.UniformPriceDetail> details = new ArrayList<>(10);
        for (SlkjTicketCategory ticketCategory : ticketCategoryList) {
            ProjectTicketFareManagementVo.UniformPriceDetail uniformPriceDetail = new ProjectTicketFareManagementVo.UniformPriceDetail();
            uniformPriceDetail.setTicketCategoryId(ticketCategory.getTicketLevelId());
            uniformPriceDetail.setTicketCategoryName(ticketCategory.getName());
            uniformPriceDetail.setUniformPrice("");
            details.add(uniformPriceDetail);
        }
        return details;
    }

    /**
     * 新增编辑 项目_票价
     *
     * @param projectTicketFareManagementDto 项目_票价
     * @param userId                         操作人ID
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertSlkjProjectTicketFare(ProjectTicketFareManagementDto projectTicketFareManagementDto, Long userId) {
        Long projectId = projectTicketFareManagementDto.getProjectId();
        log.info("执行项目 [project_id={}] 定价，编辑插入service。", projectTicketFareManagementDto.getProjectId());
        Stopwatch stopwatch = Stopwatch.createStarted();
        if (Objects.isNull(projectId)) {
            return AjaxResult.error("项目ID不能为空！");
        }

        List<ProjectTicketFareManagementDto.UniformPrice> defaultUniformPrices = projectTicketFareManagementDto.getDefaultUniformPrices();
        if (CollectionUtils.isEmpty(defaultUniformPrices)) {
            return AjaxResult.error("统一定价不能为空！");
        }

        List<SlkjProjectTicketFare> data = new ArrayList<>();
        SlkjProjectTicketFare projectTicketFare;
        log.info("先将项目 [project_id={}] 的原始票价标记为删除状态！", projectId);
        projectTicketFare = new SlkjProjectTicketFare();
        projectTicketFare.setProjectId(projectId);
        projectTicketFare.setStatus(0);
        projectTicketFare.setUpdateBy(userId + "");
        projectTicketFare.setUpdateTime(DateUtils.getNowDate());
        slkjProjectTicketFareMapper.updateProjectTicketFareByProjectId(projectTicketFare);

        log.info("默认统一定价，插入...");
        // 默认统一价 插入
        for (ProjectTicketFareManagementDto.UniformPrice dup : defaultUniformPrices) {
            projectTicketFare = new SlkjProjectTicketFare();
            projectTicketFare.setProjectId(projectId);
            projectTicketFare.setTicketLevelId(dup.getTicketLevelId());
            projectTicketFare.setTicketCategoryId(dup.getTicketCategoryId());
            projectTicketFare.setUniformPrice((long) MoneyUtils.yuan2Fen(dup.getUniformPrice()));
            projectTicketFare.setStatus(1);
            projectTicketFare.setCreateTime(DateUtils.getNowDate());
            projectTicketFare.setCreateBy(userId + "");
            data.add(projectTicketFare);
        }

        log.info("门店自定义价，插入...");
        // 门店价插入
        List<ProjectTicketFareManagementDto.ShopPrice> shopPrices = projectTicketFareManagementDto.getShopPrices();
        if (CollectionUtils.isNotEmpty(shopPrices)) {
            Map<String, ProjectTicketFareManagementDto.UniformPrice> uniformPriceMap = defaultUniformPrices.stream().collect(Collectors.toMap(uniformPrice -> uniformPrice.getTicketLevelId() + "_" + uniformPrice.getTicketCategoryId(), dup -> dup));
            for (ProjectTicketFareManagementDto.ShopPrice shopPrice : shopPrices) {
                projectTicketFare = new SlkjProjectTicketFare();
                projectTicketFare.setProjectId(projectId);
                projectTicketFare.setTicketLevelId(shopPrice.getTicketLevelId());
                projectTicketFare.setTicketCategoryId(shopPrice.getTicketCategoryId());

                // 统一价
                ProjectTicketFareManagementDto.UniformPrice uniformPrice = uniformPriceMap.get(shopPrice.getTicketLevelId() + "_" + shopPrice.getTicketCategoryId());
                projectTicketFare.setUniformPrice((long) MoneyUtils.yuan2Fen(uniformPrice.getUniformPrice()));

                // 门店价
                if (StringUtils.isNotEmpty(shopPrice.getShopPrice())) {
                    projectTicketFare.setShopPrice((long) MoneyUtils.yuan2Fen(shopPrice.getShopPrice()));
                }
                projectTicketFare.setStatus(1);
                projectTicketFare.setCreateBy(userId + "");
                projectTicketFare.setCreateTime(DateUtils.getNowDate());
                data.add(projectTicketFare);
            }
        }

        log.info("执行批量插入...");
        slkjProjectTicketFareMapper.batchInsertProjectTicketFare(data);

        log.info("项目 [project_id={}] 票价管理，共耗时：{}.", projectId, stopwatch.stop());
        return AjaxResult.success("添加成功！");
    }

    /**
     * 批量删除项目_票价
     *
     * @param ids 需要删除的项目_票价主键
     * @return 结果
     */
    @Override
    public int deleteSlkjProjectTicketFareByIds(Long[] ids) {
        return slkjProjectTicketFareMapper.deleteSlkjProjectTicketFareByIds(ids);
    }

    /**
     * 删除项目_票价信息
     *
     * @param id 项目_票价主键
     * @return 结果
     */
    @Override
    public int deleteSlkjProjectTicketFareById(Long id) {
        return slkjProjectTicketFareMapper.deleteSlkjProjectTicketFareById(id);
    }
}
